/* -----------------------------------------------------------------------
 *   Copyright (C) 2008 by Denjs
 *   dplsoft@pisem.net
 *   http://qdroid.berlios.de
 * -----------------------------------------------------------------------
 *   This program is free software licensed under GNU GPL License v.2 ; see main.cpp fo details
 *   Эта программа является свободным программным обеспечением; распространяемым под
 *   лицензией GNU General Public License v.2 (УНИВЕРСАЛЬНАЯ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ GNU версия 2.0) 
 * ----------------------------------------------------------------------- */
/*
 * t_FileList.h
 *
 *  Created on: 21.11.2008
 *      Author: Denjs
 *
 *  	ver 2008.12.04
 *      ver 2008.11.25
 */

#ifndef t_FileList_H_
#define t_FileList_H_

#include "t_AbstractQDroidBot.h"
#include <QList>
#include <QSet>
#include <QMap>
#include <QtXml>
 #include <QAbstractItemModel>
 #include <QModelIndex>
 #include <QListWidget>
 #include <QTreeWidget>
#include "t_FileListElement.h"
#include "t_TreeWidget.h"

/*
 Класс для обработки списков файлов.
 Наследуем от "абстрактного бота"

регистрирует для среды скрипта ссылку на свой тип.
описывает необходимое для добвления в некотрые контейнерные классы.

предполагается, что будет адаптирован
	для прямого отображения в QTreeView

TODO добавить поддержку свойств самого списка.
	Например для того что бы отслеживать дату сохранения списка.
TODO загружать и хранить несколько списков в одном XML-файле? что-то типа хранилища?

*/

class t_FileList : public t_AbstractQDroidBot
{
    Q_OBJECT

    public:
    	t_FileList(QObject *parent =0);

    	//это (ниже) нужно что бы можно было засунуть t_FileList в контейнер QList
    	// возможно так-же связано с работой QtScript движка - см функции после определения класса
    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 1 из 8
    	t_FileList(const t_FileList &other);
    	//это (ниже) нужно что бы можно было засунуть t_FileList в контейнер QList
    	// возможно так-же связано с работой QtScript движка - см функции после определения класса
    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 2 из 8
    	t_FileList& operator=(const t_FileList &other);


    	t_FileListElement CurrentElementCopy;
    	QList<t_FileListElement> FileList;  // основной список
    	QSet<t_FileListElement> FileSet;	// нужен при операциях над множествами (для сравнения, пересечения и т.п.)
				// т.к. t_FileListElement определен верно, то мы можем достаточно свободно конвертировать
				// между List и Set

    public slots:
		QString std_in(QString Message); // needs to be redefined to make real class
		t_FileList* copy();//костыли в рузультуате того что регистрируем ссылку а не сам тип для движка

	/*ОПЕРАЦИИ НАД ЭЛЕМЕНТАМИ*/
		//код возврата "-1" и другие менее 0, означают ошибку!
		int add(t_FileListElement *FileListElement,int position =-1);//добавить в заданную позицию
		t_FileListElement* get(int position);//вернуть копию элемента из заданной позиции
		int get_pos_by_id(QString _id_value);//для поиска элемента по ID - вернуть позицию элемента c заданным ID
		int replace(t_FileListElement *FileListElement,int position );// замена элемента в всписке
		int remove(int position);//удалить элемент в позиции
		int clear();//удалить элемент в позиции
		int size();//вернуть количество элементво в списке

	/*ОПЕРАЦИИ С ФАЙЛАМИ*/
		QString update_from_dir(QString _DirectoryPath,int DirDeep =0, QString _MissFileMask="");//обновить список файлов из каталога
			//2009.09.01 + _MissFileMask
		int fill_relative_paths(QString _DirectoryPath);//заполнить поле относительного пути.
		
		//TODO сохранение/восстановление в/из файла
		// xml?
		QString save_to_file(QString _FIleFullName);
		QString load_from_file(QString _FileFullName);

	/*ОПЕРАЦИИ КАК С МНОЖЕСТВАМИ*/
		//NOTE: контроль уникальности долбавляемых элементов явно не ведется,
		// но после первой-же операции с множествами дубли "по ID" будут удалены.
		/* сравнение производится как
		 * операции над множествами.
		 * анализируется t_FileListElement.ID элемента
		 * Принудительно он перезаполняется в результате
		 * 			fill_relative_paths
		 * ВНИМАНИЕ! врезультате операций над множествами теряется порядок элементов!
		 */
		 /*a AND b*/
		 int intersect(t_FileList *OtherFileList);//пересечь множества (AND)
					// без объединения атрибутов при пересечении.
					// какой конкретно экземпляр попадет итоговое множество - не известно
		 int intersect_w_properties(t_FileList *OtherFileList, bool ReplacePropertyValues=true, bool UnitePropertySets=true);//пересечь множества (AND)
				// c объединением атрибутов при пересечении.
					// замещать текущий набор свойств
					// НЕ замещать текущий набор свойств
					// объединить наборы свойств с приоритетом новых значений при совпадении имени
					// объединить наборы свойств с приоритетом старых значений при совпадении имени


		 /*a OR b*/ /*a + b*/
		 int unite(t_FileList *OtherFileList);//объединить множества (OR)
						// без объединения атрибутов при пересечении.
						// какой конкретно экземпляр попадет итоговое множество - не известно
		 int unite_w_properties(t_FileList *OtherFileList, bool ReplacePropertyValues=true, bool UnitePropertySets=true);//объединить множества (OR)
				// c объединением атрибутов при пересечении.
					// замещать текущий набор свойств
					// НЕ замещать текущий набор свойств
					// объединить наборы свойств с приоритетом новых значений при совпадении имени
					// объединить наборы свойств с приоритетом старых значений при совпадении имени
		 /*a AND(NOT b)*/ /*a - b*/
		 int subtract(t_FileList *OtherFileList);//вычесть из текущего множества другое множество (AND)
		 /*a XOR */
		 int exclusive_unite(t_FileList *OtherFileList);//(XOR)
		 //TODO? FillIdFrom({FieldName}) - занести в ID значение заданного поля.

	/*ОПЕРАЦИИ С МНОЖЕСТВАМИ и аитрибутами элементов*/
		 //составить список из элементов где заданное свойство имеет заданное значение
		 t_FileList* sort_out_by_property(QString _ValueName,QString _ValueVar);

		 //TODO? SortListBy({FieldName}) - СОРТИРОВКА СПИСКА ФАЙЛОВ!

		 //обмен между списками - см операции над множествами
		 // но как работать со списком-  например вставить между и т.п.?
		 // ввести дробный показатель "OrderValue" ? для целей сортировки?

	/*ОПЕРАЦИИ С GUI*/
		t_TreeWidget *create_tree_widget(QString PropertyOrder="");
		int make_tree_struct();

		// TODO переописать класс как источник данных для модели "модель-представление-контроллер"

	/* ГРУППОВЫЕ ОПЕРАЦИИ НАД АТРИБУТАМИ элементов*/
		int set_property(QString _ValueName,QString _ValueVar);//установить у элементов свойства
		int count_item_property_enteries(QString _ValueName); //вернуть количество элементов в которых определено свойство
		int remove_item_property(QString _ValueName); //удалить заданное свойство элементов
		int remove_all_item_properties();//удалить все свойства элементов
		int rename_item_property(QString _ValueNameOld, QString _ValueNameNew, bool Replace=true);//переименовать свойство.

    signals:

    protected:
    	QList<t_FileListElement> get_intersection_w_properties(t_FileList *OtherFileList, bool ReplacePropertyValues, bool UnitePropertySets);
    private:

};
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//нужно чтобы можно было передавать эти элементы как параметры в функции внутри QtScript
// спец. настройки для QtScript (v 2008.11.25)
// Шаг 3 из 8
Q_DECLARE_METATYPE(t_FileList*);

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 4 из 8
static QScriptValue qdroid_t_FileList_toScriptValue(QScriptEngine *engine, t_FileList* const &in)
{ return engine->newQObject(in); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 5 из 8
static void qdroid_t_FileList_fromScriptValue(const QScriptValue &object, t_FileList* &out)
{ out = qobject_cast<t_FileList*>(object.toQObject()); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 6 из 8
//конструктор для последующего его определения как new в скрипте
static QScriptValue qdroid_t_FileList_constructor(QScriptContext *QSContext, QScriptEngine *QSEngine)
	{
		//t_BaseBot BaseBot;
		QScriptValue QtSObject;
		QtSObject=QSEngine->newQObject(new t_FileList()); //
		//qsBaseBot=QSEngine->toScriptValue(BaseBot);
		return QtSObject;
	}

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 7 из 8
// - это qScriptRegisterMetaType регистрация но это нужно сделать в головном классе
// например в глобальной функции "define__qdroid_qtscript_functions()"
//// t_FileList TYPE defenition
//	qScriptRegisterMetaType(_QSEngine, qdroid_t_FileList_toScriptValue, qdroid_t_FileList_fromScriptValue);

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 8 из 8
//- определение конструктора в контексте скрипта
//// t_FileList NEW constructor defenition
//	QScriptValue fun4_constr = _QSEngine->newFunction(qdroid_t_FileList_constructor);
//	_QSEngine->globalObject().setProperty("t_FileList", fun4_constr);

/*
//==[QTreeWidget*]====================================================
Q_DECLARE_METATYPE(QTreeWidget*);

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 4 из 8
static QScriptValue qdroid_QTreeWidgetP_toScriptValue(QScriptEngine *engine, QTreeWidget* const &in)
{ return engine->newQObject(in); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 5 из 8
static void qdroid_QTreeWidgetP_fromScriptValue(const QScriptValue &object, QTreeWidget* &out)
{ out = qobject_cast<QTreeWidget*>(object.toQObject()); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 6 из 8
//конструктор для последующего его определения как new в скрипте
static QScriptValue qdroid_QTreeWidgetP_constructor(QScriptContext *QSContext, QScriptEngine *QSEngine)
	{
		//t_BaseBot BaseBot;
		QScriptValue QtSObject;
		QtSObject=QSEngine->newQObject(new QTreeWidget()); //
		//qsBaseBot=QSEngine->toScriptValue(BaseBot);
		return QtSObject;
	}

//// at global_qs_functions.h ::
//// QTreeWidget* TYPE defenition
//	qScriptRegisterMetaType(_QSEngine, qdroid_QTreeWidgetP_toScriptValue, qdroid_QTreeWidgetP_fromScriptValue);

//// QTreeWidget* NEW constructor defenition
//	QScriptValue QTreeWidgetP_constr = _QSEngine->newFunction(qdroid_QTreeWidgetP_constructor);
//	_QSEngine->globalObject().setProperty("QTreeWidget", QTreeWidgetP_constr);

*/

//=================================================================

#endif /* t_FileList_H_ */
